/**
 * Created by 黄健 on 2015-05-20.
 * 描述：此文件中的JS代码主要用于定义UI界面元素
 */

var $topNavbar;//定义顶部导航栏对象
var $main;//定义主界面对象
var $accidentTreeCanvas;//定义画布对象
var $atcContentMenu;//定义画布右键菜单对象
var $treeNodeContentMenu;//定义节点右键菜单
var $nodeInfoForm;
var $styleInfoForm;
var selectedNodes = [];//定义记录框选中的节点

$(function(){
    $topNavbar = $("#topNavbar");
    $main = $("#main");
    $accidentTreeCanvas = $("#accidentTreeCanvas");
    $atcContentMenu = $("#accidentTreeCanvasContentMenu");
    $treeNodeContentMenu = $("#treeNodeContentMenu");
    $nodeInfoForm = $("#nodeInfoForm");
    $styleInfoForm = $("#styleInfoForm");

    /*window.onbeforeunload = function(){
        return "离开前请先确认您是否需要保存当前操作！";
    };

    document.body.onbeforeunload = function (event)
    {
        var c = event || window.event;
        if (/webkit/.test(navigator.userAgent.toLowerCase())) {
            return "离开前请先确认您是否需要保存当前操作！";
        }
        else
        {
            c.returnValue = "离开前请先确认您是否需要保存当前操作！";
        }
    };*/

    initMainHeight($main);

    //清空节点信息表单
    clearNodeInfoForm($nodeInfoForm);
    clearNodeInfoForm($styleInfoForm);

    //页面窗口大小改变之后触发
    window.onresize = function(event){
        initMainHeight($main);
    };

    //给画布添加右键菜单
    $accidentTreeCanvas.bind("contextmenu", function(e){
        if(e.target.farthestViewportElement && e.target.farthestViewportElement._jsPlumb){
            return false;
        }
        var mouseCoord = getPositionByObj(e, "accidentTreeCanvas");
        var x = parseInt(mouseCoord.x);
        var y = parseInt(mouseCoord.y);
        //alert("x="+x+",y="+y);
        $atcContentMenu.show();
        $atcContentMenu.css("left", x+"px");
        $atcContentMenu.css("top", y+"px");
        return false;
    });

    //画布绑定鼠标单击事件
    $accidentTreeCanvas.mousedown(function (e) {
        if(e.which == 1){//画布单击
            var localName = e.target.localName;
            //如果单击的目标是input、textarea，则返回true，让单击可以激活元素
            if(localName === "input" || localName === "textarea"){


                return true;
            }else{
                $atcContentMenu.hide();
                //取消画布中被选中的节点
                $(".nodeActive").removeClass("nodeActive");
                //隐藏节点右键菜单
                $treeNodeContentMenu.hide();
                //清空节点信息表单
                clearNodeInfoForm($nodeInfoForm);
                clearNodeInfoForm($styleInfoForm);
            }
            return false;
        }
    });

    $("#canvasSizeSettingModal").on("shown.bs.modal", function (e) {
        //$("#canvasWidthInput").focus();
        $("#canvasWidthInput").val($accidentTreeCanvas.width());
        $("#canvasHeightInput").val($accidentTreeCanvas.height());
    });

    $("#showTreeDataModal").on("shown.bs.modal", function (e) {
        $("#treeDataStr").text(JSON.stringify(treeData));
        $("#selectAllCopy").zclip({
            path: "resources/js/zclip/ZeroClipboard.swf",
            beforeCopy: function(){

            },
            copy: function(){
                return $("#treeDataStr").text();
            },
            afterCopy: function(){
                alert("成功复制至剪切板");
                //$("<span class='msg'/>").insertBefore($("#selectAllCopy")).text("复制成功").fadeOut(2000);
                //mini.alert("成功复制至剪切板");
            }
        });
    });

    $("#showTreeDataModal").on("hidden.bs.modal", function (e) {
        $("#selectAllCopy").unbind();//取消复制按钮的全部绑定的事件
    });

    $("#loadTreeDataModal").on("shown.bs.modal", function (e) {
        $("#treeDataTextarea").focus();
        $("#treeDataTextarea").on("keypress", function (event) {
            if(event.keyCode == 13) {
                loadTreeData();
            }
        });
    });

    $("#loadTreeDataModal").on("hidden.bs.modal", function (e) {
        $("#treeDataTextarea").val("");
        $("#treeDataTextarea").unbind();
    });

    $("#versionLogModal").on("shown.bs.modal", function (e) {
        //$("#versionLogBody").load("versionLog.html");
    });

    //给画布注册框选事件
    $accidentTreeCanvas.selectable({
        filter: ".node",
        selecting: function(event){

        },
        start: function(event, ui){
            //$.getScript("resources/js/jsplumb/dom.jsPlumb.js");
        },
        stop: function(event, ui){
            selectedNodes = $accidentTreeCanvas.find(".ui-selected");
            for(var i = 0; i<selectedNodes.length; i++){
                instance.addToDragSelection(selectedNodes[i]);
            }
        },
        unselected: function(event, ui){
            for(var i = 0; i<selectedNodes.length; i++){
                instance.removeFromDragSelection(selectedNodes[i]);
            }
            selectedNodes = [];//清空selectedNodes
            //$("script[src='resources/js/jsplumb/dom.jsPlumb.js']").remove();
        }
    });

    $(".tool").draggable({
        helper:"clone",//设置helper属性为复制
        //containment: "parent",//设置数据源能拖动的范围
        //snap: "#accidentTreeCanvas",//设置吸附
        //handle: ".panel-heading",//设置某个元素作为拖动的把手
        revert: "invalid",//指定当drop失败时source“飘”回原来的位置
        cursor: "move",//指定拖动时鼠标指针的形状
        cursorAt: { top: 25, left: 25 },//指定鼠标指针在source的相对位置
        start: function(event, ui){

        },
        stop: function(event, ui){

        }
    });

    $accidentTreeCanvas.droppable({
        accept: '.tool',
        activate: function(event,ui) {

        },
        over: function(event,ui) {

        },
        out: function(event,ui) {

        },
        drop: function(event, ui) {

            var mousePosition = getPositionByObj(event, "accidentTreeCanvas");
            var toolId = ui.draggable.context.attributes.getNamedItem("id").value;
            var nodeType = ui.draggable.context.attributes.getNamedItem("data-nodeType").value;
            var subType = "";

            //判断当前拖拽的是否是省略事件，如果是，则赋值子类型为SLSJ
            if(toolId == "slsjTool"){
                subType = "SLSJ";
            }else if(toolId == "zcsjTool"){
                subType = "ZCSJ";
            }

            var nodeData = {
                type: ""+nodeType,
                subType: ""+subType,//子类型，例如基本事件下的省略事件
                key: ""+createUuid(),
                name: "",
                number: "",//编号
                position: [""+mousePosition.x, ""+mousePosition.y],
                size: {"width":"", "height":""},
                parentKey: ""
            };

            if(us.isEmpty(treeData)){
                if(nodeData.type != treeNodeTypeObj.T){
                    alert("必须拥有一个顶上事件");
                    return false;
                }
            }else{
                if(nodeData.type == treeNodeTypeObj.T){
                    alert("顶上事件只能有一个，不能重复添加");
                    return false;
                }
            }

            //判断如果拖拽的是与门或或门，就直接添加，不需要输入名称
            if(nodeData.type == treeNodeTypeObj.YM || nodeData.type == treeNodeTypeObj.HM){
                addNode(nodeData);
            }else{
                var result = showPrompt();
                if(result != null){
                    nodeData.name = result;
                    addNode(nodeData);
                }
            }

        }
    });

    //给节点信息表单中的Input注册回车监听事件
    $(".infoInput").on("keypress", function (event) {
        if(event.keyCode == 13) {
            var value = replaceBlank(event.target.value);
            var $nodeActive = $(".nodeActive");
            switch (event.target.id){
                case "nodeNameInput":
                    updateNodeNameHandler($nodeActive, value);
                    break;
                case "nodeWidthInput":
                    $nodeActive.css("width", value+"px");
                    us.each(treeData, function(item, i){
                        if(item.key == $nodeActive.attr("data-nodeKey")){
                            item.size.width = value;
                        }
                    });
                    instance.repaintEverything();
                    break;
                case "nodeHeightInput":
                    $nodeActive.css("height", value+"px");
                    us.each(treeData, function(item, i){
                        if(item.key == $nodeActive.attr("data-nodeKey")){
                            item.size.height = value;
                        }
                    });
                    instance.repaintEverything();
                    break;
                case "nodeXInput":
                    $nodeActive.css("left", value+"px");
                    us.each(treeData, function(item, i){
                        if(item.key == $nodeActive.attr("data-nodeKey")){
                            item.position[0] = value;
                        }
                    });
                    instance.repaintEverything();
                    break;
                case "nodeYInput":
                    $nodeActive.css("top", value+"px");
                    us.each(treeData, function(item, i){
                        if(item.key == $nodeActive.attr("data-nodeKey")){
                            item.position[1] = value;
                        }
                    });
                    instance.repaintEverything();
                    break;
            }
        }
    });

    //绑定键盘ctrl+s事件
    $(document).keydown(function(event){
        if (event.ctrlKey && event.keyCode==83){
            //console.log("保存");
            return false;
        }
    });

    //绑定键盘方向按键，如果画布中存在被选中的节点，那么就控制节点移动
    //jsPlumb.repaintEverything();重新绘制节点，实现连接点跟随移动
    $(document).keydown(function(e){
        var $selectedNodes = [];
        if(selectedNodes.length > 0){
            us.each(selectedNodes, function(item, i){
                $selectedNodes.push($("#"+$(item).attr("id")))
            });
        }else{
            $selectedNodes.push($(".nodeActive"));
        }
        //var $nodeActive = $(".nodeActive");
        var id = e.keyCode;
        switch (id){
            case 67:
                if($atcContentMenu.css("display") == "block"){
                    clearTree();
                }
                break;
            case 68:
                if($treeNodeContentMenu.css("display") == "block"){
                    removeTreeNode();
                }
                break;
            case 69:
                if($atcContentMenu.css("display") == "block"){
                    location.reload();
                }
                break;
            case 86:
                if($atcContentMenu.css("display") == "block"){
                    resetCanvasSize();
                }
                break;
            case 87:
                if($atcContentMenu.css("display") == "block"){
                    checkTreeData();
                }
                break;

            case 37:
                us.each($selectedNodes, function(item, i){
                    item.css("left", (parseInt(item.css("left"))-1)+"px");
                    updateNodeDivPosition(item);
                    jsPlumb.repaintEverything();
                });
                updateInfoDiv_position($(".nodeActive"));
                return false;
                break;
            case 38:
                us.each($selectedNodes, function(item, i){
                    item.css("top", (parseInt(item.css("top"))-1)+"px");
                    updateNodeDivPosition(item);
                    jsPlumb.repaintEverything();
                });
                updateInfoDiv_position($(".nodeActive"));
                return false;
                break;
            case 39:
                us.each($selectedNodes, function(item, i){
                    item.css("left", (parseInt(item.css("left"))+1)+"px");
                    updateNodeDivPosition(item);
                    jsPlumb.repaintEverything();
                });
                updateInfoDiv_position($(".nodeActive"));
                return false;
                break;
            case 40:
                us.each($selectedNodes, function(item, i){
                    item.css("top", (parseInt(item.css("top"))+1)+"px");
                    updateNodeDivPosition(item);
                    jsPlumb.repaintEverything();
                });
                updateInfoDiv_position($(".nodeActive"));
                return false;
                break;
        }
    });
});

/**
 * 更新右侧信息栏中的坐标信息
 * @param _nodeActiveObj 当前鼠标单击选中的节点
 */
function updateInfoDiv_position(_nodeActiveObj){
    var $nodeXInput = $("#nodeXInput");
    var $nodeYInput = $("#nodeYInput");
    $nodeXInput.val(_nodeActiveObj.css("left").replace("px",""));
    $nodeYInput.val(_nodeActiveObj.css("top").replace("px",""));
}

/**
 * 封装节点名称修改之后的处理逻辑
 * @param _nodeActiveObj 当前激活节点对象
 * @param _value 备修改值
 */
function updateNodeNameHandler(_nodeActiveObj, _value){
    if(_value.length == 0){
        alert("请输入名称，注意：空格无效！");
        return false;
    }
    var $nodeNameSpan = _nodeActiveObj.find(".nodeNameSpan");//先拿到名称显示的Span元素
    var newNumber = null;//定义新编号变量，如果输入的名称在数据串中存在，才会给它赋值
    //获取当前操作节点对应数据串中的数据
    var currentActiveNode = findTreeNode(_nodeActiveObj.attr("data-nodeKey"), treeData);
    //开始遍历全局数据串
    us.each(treeData, function(item, i){
        //如果数据串中存在和当前输入名称相同的节点，那就获取其编号赋给newNumber，并且设置DIV节点的角标
        if(item.name == _value && item.type == currentActiveNode.type){
            _nodeActiveObj.find(".nodeMark").text(item.number);
            newNumber = item.number;
        }
    });
    //开始遍历数据串，处理当前选中的节点信息
    us.each(treeData, function(item, i){
        if(item.key == _nodeActiveObj.attr("data-nodeKey")){
            item.name = _value;
            if(newNumber){
                item.number = newNumber;
            }else{
                var flag = false;
                var currentNumber = item.number;
                us.each(treeData, function (item2, i) {
                    if(currentNumber == item2.number && item2.key != item.key){
                        flag = true;
                    }
                });
                if(flag){
                    var newItem = nodeNumberHandle(item);
                    item.number = newItem.number;
                    _nodeActiveObj.find(".nodeMark").text(item.number);
                }
            }
        }
    });
    $nodeNameSpan.text(cutNodeName(_value));
    _nodeActiveObj.attr("title", _value);
}

/**
 * 清空表单
 * @param _form
 */
function clearNodeInfoForm(_form){
    $(':input', _form).each(function() {
        var type = this.type;
        var tag = this.tagName.toLowerCase();
        if (type == 'text' || type == 'password' || tag == 'textarea')
            this.value = "";
        else if (type == 'checkbox' || type == 'radio')
            this.checked = false;
        else if (tag == 'select')
            this.selectedIndex = -1;
    });
}


function initNodeSize(_nodeObj){
    var $nodeNameSpan = _nodeObj.find(".nodeNameSpan");
    var spanWidth = parseInt($nodeNameSpan.css("width").replace("px",""));
    var spanHeight = parseInt($nodeNameSpan.css("height").replace("px",""));
    var nodeWidth = parseInt(_nodeObj.css("width").replace("px",""))
    var nodeHeight = parseInt(_nodeObj.css("height").replace("px",""));
    var nodeMinHeight = parseInt(_nodeObj.css("min-height").replace("px",""));


    if(spanHeight > nodeHeight){
        _nodeObj.css("height", (spanHeight+12)+"px");
    }
    if(spanHeight < nodeMinHeight){
        _nodeObj.css("height", nodeMinHeight+"px");
    }

    instance.repaintEverything();

}

/**
 * 初始化主界面内容高度，实现主界面高度随浏览器窗口变化而变化
 * @param _obj 目标对象
 */
function initMainHeight(_obj){
    var len = document.documentElement.clientHeight;//获取浏览器内容区高度
    _obj.css("height", (len-$topNavbar.height())+"px");//设置主界面内容高度为len减去顶部导航栏高度
}

/**
 * 保存画布大小设置（暂时没有做任何校验）
 */
function saveCanvasSizeSetting(){
    var canvasContainerWidth = parseInt($("#canvasContainer").css("width").replace("px",""));
    var canvasContainerHeight = parseInt($("#canvasContainer").css("height").replace("px",""));

    var inputWidth = parseInt($("#canvasWidthInput").val());
    var inputHeight = parseInt($("#canvasHeightInput").val());

    /*if(inputWidth < canvasContainerWidth || inputHeight < canvasContainerHeight){
        alert("设置的宽度或高度不能低于画布容器的最低值");
    }else{
        $accidentTreeCanvas.width($("#canvasWidthInput").val());
        $accidentTreeCanvas.height($("#canvasHeightInput").val());
        updateTreeDataCanvasSize();
        $("#canvasSizeSettingModal").modal("hide");
    }*/
    $accidentTreeCanvas.css("width", $("#canvasWidthInput").val()+"px");
    $accidentTreeCanvas.css("height", $("#canvasHeightInput").val()+"px");
    updateTreeDataCanvasSize();
    $("#canvasSizeSettingModal").modal("hide");
}

/**
 * 重置画布大小
 */
function resetCanvasSize(){
    $accidentTreeCanvas.css("width", "100%");
    $accidentTreeCanvas.css("height", "100%");
    updateTreeDataCanvasSize();
    $atcContentMenu.hide();
}

/**
 * 刷新应用
 */
function refreshMain(){
    location.reload();
}

/**
 * 确认输入框
 * @returns {*} 返回输入的内容
 */
function showPrompt(){
    var value = prompt("请输入名称：", "");
    if(value == null){
        //alert("您取消了输入");
        return null;
    }else{
        value = replaceBlank(value);//替换空格
    }

    if(value == ""){
        alert('请输入名称');
        showPrompt();
    }else{
        return value;
    }
}

/**
 * 替换空格
 * @param _val
 * @returns {string}
 */
function replaceBlank(_val){
    return _val.replace(/\s+/g,'').replace(/\s\s*$/,'');
}

/**
 * 截取节点名称，如果名称长度大于指定长度，则截取，末尾使用省略号替代
 * @param _nodeName
 * @param _length
 * @returns {string}
 */
function cutNodeName(_nodeName, _length){
    var length = 10;
    if(_length){
        length = _length;
    }
    if(_nodeName.length > length){
        _nodeName = _nodeName.substring(0, length)+"...";
        return _nodeName;
    }else{
        return _nodeName;
    }
}

/**
 * 隐藏节点信息栏
 */
function hideInfoDiv(_btn){
    classie.toggle(_btn, 'active');
    classie.toggle(document.body, 'cbp-spmenu-push-toleft');
    classie.toggle(document.getElementById('infoDiv'), 'cbp-spmenu-open');
    var $infoDiv = $("#infoDiv");
    if($infoDiv.hasClass("cbp-spmenu-open")){
        $("#canvasContainer").removeClass("col-xs-11").addClass("col-xs-9");
        $("#showInfoDivBtn").hide();
    }else{
        $("#canvasContainer").removeClass("col-xs-9").addClass("col-xs-11");
        $("#showInfoDivBtn").show();
    }
    return false;
}

/**
 * 获取鼠标相对于body元素的坐标
 * @param event
 * @returns {{x: (number|Number|clientX|*), y: (number|Number|clientY|*)}}
 */
function getPositionByBody(event) {
    event = event || window.event;
    //获得相对于body定位的横标值；
    var x = event.clientX;
    //获得相对于body定位的纵标值；
    var y = event.clientY;
    return {"x": x, "y": y};
}

/**
 * 获取相对于某一容器内的鼠标坐标
 * @param event
 * @param id 容器ID
 * @returns {{x: number, y: number}}
 */
function getPositionByObj(event, id){
    /*//获得对象相对于页面的横坐标值；id为对象的id
    var thisX = document.getElementById(id).offsetLeft;
    //获得对象相对于页面的横坐标值；
    var thisY = document.getElementById(id).offsetTop;
    //获得页面滚动的距离；
    //注：document.documentElement.scrollTop为支持非谷歌内核；document.body.scrollTop为谷歌内核
    var thisScrollTop = document.documentElement.scrollTop + document.body.scrollTop;
    event = event||window.event;
    //获得相对于对象定位的横标值 = 鼠标当前相对页面的横坐标值 - 对象横坐标值；
    var x = event.clientX - thisX;
    //获得相对于对象定位的纵标值 = 鼠标当前相对页面的纵坐标值 - 对象纵坐标值 + 滚动条滚动的高度；
    var y = event.clientY - thisY + thisScrollTop;
    return {"x": x, "y": y};*/

    var offset = $("#"+id).offset();
    var relativeX = (event.pageX - offset.left);
    var relativeY = (event.pageY - offset.top);
    return {"x": relativeX, "y": relativeY};
}